/** 
 * Copyright (C) 2012 Foxit Corporation.
 * All Rights Reserved.
 *
 * The following code is copyrighted and contains proprietary information and trade secrets of Foxit Corporation.
 * You can only redistribute files listed below to customers of your application, under a written SDK license agreement with Foxit. 
 *	You cannot distribute any part of the SDK to general public, even with a SDK license agreement. 
 * Without SDK license agreement, you cannot redistribute anything.
 *
 * @file	fgsdrm.h
 * @brief	Header file for the Base Drm module.
 * @details	This is the base drm module in this SDK. Other drm modules can use this base module.
 *			It contains:<br>
 *			1. Supporting the operation of Foxit Category handle.Such as getting,getting the attribute value,<br>
 *			   setting the attribute value,adding and removing.<br>
 *			2. Supporting the operation of Foxit Foac handle. Such as creating,saving,getting attribute value,<br>
 *			   setting attribute vale and getingt category handle.<br>
 *			3. Supporting the operation of Foxit Envelop handle.Such as creating,saving,getting attribute value<br>
 *			   and setting attribute value.
 *
 * @note	If you want to purchase Foxit PDF SDK license and use ANY of the following functions, please
 *			request for enabling Base DRM module explicitly. 
 */

/** 
 * @addtogroup FGSDRM Base Drm
 * @brief Methods in this module are included in fgsdrm.h.
 */
/**@{*/

#ifndef __FGSDRM__
#define __FGSDRM__

#include "../rt/fgs.h"

#ifdef __cplusplus
extern "C" {
#endif

/** @brief The drm category reference type. */
typedef const struct __FGSDrmCategory * FGSDrmCategoryRef;

/**
 * @brief Count the number of the sub category.
 *
 * @param[in] category				Reference to a category.
 * @param[in] filter				The filter string.
 *
 * @return	Reference to a category.
 *
 */
SInt32 FGSDrmCategoryCountSubCategories(FGSDrmCategoryRef category, CFStringRef filter);

/**
 * @brief Get the specified sub category.
 *
 * @param[in] category				Reference to a category.
 * @param[in] filter				The filter string.
 * @param[in] index					The index of the sub cateogry which to get.
 *
 * @return	Reference to a category.
 *
 */
FGSDrmCategoryRef FGSDrmCategoryGetSubCategory(FGSDrmCategoryRef category, CFStringRef filter, SInt32 index);

/**
 * @brief Get the attribute value of the specified sub category.
 *
 * @param[in] category				Reference to a category.
 * @param[in] attriName				The attribute name which to get, user should release the string by calling <b>CFRelease</b>.
 *
 * @return	An attribute value string, user should release the string by calling <b>CFRelease</b>.
 *
 */
CFStringRef	FGSDrmCategoryCopyAttributeValue(FGSDrmCategoryRef category, CFStringRef attriName);

/**
 * @brief Get the data of the specified sub category.
 *
 * @param[in] category				Reference to a category.
 *
 * @return	An data string, user should release the string by calling CFRelease.
 *
 */
CFStringRef FGSDrmCategoryCopyData(FGSDrmCategoryRef category);

/**
 * @brief Add a sub category.
 *
 * @param[in] category				Reference to a category.
 * @param[in] name					The name of the sub category.
 * @param[in] uniqueName			Specifying the name of the sub category wether is unique.
 *
 * @return	Reference to a category.
 *
 */
FGSDrmCategoryRef FGSDrmCategoryAddSubCategory(FGSDrmCategoryRef category, CFStringRef name, Boolean uniqueName);

/**
 * @brief Set the attribute value of the specified category.
 *
 * @param[in] category				Reference to a category.
 * @param[in] name					The name of the attribute.
 * @param[in] uniqueName			Specifying the name of the sub category whether is unique.
 * @param[in] attriValue			The attribute value.
 *
 * @return	::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 *
 */
FGSErrorRet FGSDrmCategorySetAttribute(FGSDrmCategoryRef category, CFStringRef attriName, CFStringRef attriValue);

/** @brief FOAC reference type. */
typedef const struct __FGSDrmFoac * FGSDrmFoacRef;

/**
 * @brief Load a foac reference.
 *
 * @param[in] buffer				The data which is loaded.
 *
 * @return	Reference to a foac.
 *
 */
FGSDrmFoacRef FGSDrmFoacLoadFoac(CFDataRef buffer);

/**
 * @brief Create a foac reference.
 *
 * @param[in] requestOrAnswer		To specify the foac is requesting or answering. 
 *
 * @return	Reference to a foac.
 *
 */
FGSDrmFoacRef FGSDrmFoacCreateFoac(Boolean requestOrAnswer);

/**
 * @brief Save a foac reference.
 *
 * @param[in] foac					Reference to a foac.
 * @param[out] buffer				The MutableData to store return data.
 *
 * @return	::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 *
 */
FGSErrorRet FGSDrmFoacSaveFoac(FGSDrmFoacRef foac, CFMutableDataRef buffer);

/**
 * @brief Release a foac reference.
 *
 * @param[in] foac					Reference to a foac.
 *
 * @return	::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 *
 */
FGSErrorRet	FGSDrmFoacReleaseFoac(FGSDrmFoacRef foac);
    
/**
 * @brief Set session ID.
 *
 * @param[in] foac					Reference to a foac.
 * @param[in] sessionID				The string which store session ID data.
 *
 * @return	::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 *
 */
FGSErrorRet	FGSDrmFoacSetSessionID(FGSDrmFoacRef foac, CFStringRef sessionID);

/**
 * @brief Set request ID.
 *
 * @param[in] foac					Reference to a foac.
 * @param[in] requestID				The string which stored request ID data.
 *
 * @return	::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 *
 */
FGSErrorRet	FGSDrmFoacSetRequestID(FGSDrmFoacRef foac, CFStringRef requestID);
    
/**
 * @brief Get the answer state.
 *
 * @param[in] foac					Reference to a foac.
 *
 * @return	A string store the answer state data, user should release the string by calling <b>CFRelease</b>.
 *
 */
CFStringRef	FGSDrmFoacCopyAnswerState(FGSDrmFoacRef foac);

/**
 * @brief Get the data category.
 *
 * @param[in] foac					Reference to a foac.
 *
 * @return	Reference to a category.
 *
 */
FGSDrmCategoryRef FGSDrmFoacGetDataCategory(FGSDrmFoacRef foac);

/**
 * @brief Release the data category.
 *
 * @param[in] foac					Reference to a foac.
 * @param[in] dataCategory			Reference to a category.
 *
 * @return	::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 *
 */
FGSErrorRet	FGSDrmFoacReleaseDataCategory(FGSDrmFoacRef foac, FGSDrmCategoryRef dataCategory);
    
/** @brief envelope reference type. */
typedef const struct __FGSDrmEnvelope * FGSDrmEnvelopeRef;

/**
 * @brief Load an envelope.
 *
 * @param[in] fileStream            Reference to a <b>::FGSFileStreamInRef</b>.
 *
 * @return	Reference to an envelope.
 *
 */
FGSDrmEnvelopeRef FGSDrmEnvelopeLoadEnvelope(FGSFileStreamInRef fileStream);

/**
 * @brief Validate envelope data.
 *
 * @param[in] envelope				Reference to an envelope.
 *
 * @return	Specify whether the envelop data is correct.
 *
 */
Boolean	FGSDrmEnvelopeValidateEnvelope(FGSDrmEnvelopeRef envelope);

/**
 * @brief Release an envelope.
 *
 * @param[in] envelope				Reference to an envelope.
 *
 * @return	::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 *
 */
FGSErrorRet	FGSDrmEnvelopeReleaseEnvelope(FGSDrmEnvelopeRef envelope);

/**
 * @brief Get the algorithm data.
 *
 * @param[in] envelope				Reference to an envelope.
 *
 * @return	The algorithm string that get, user should release the string by calling <b>CFRelease</b>.
 *
 */
CFStringRef	FGSDrmEnvelopeCopyAlgorithm(FGSDrmEnvelopeRef envelope);
	
/**
 * @brief Get the key.
 *
 * @param[in]  envelope				Reference to an envelope.
 * @param[out] data                 The MutableData to store key data.
 *
 * @return	::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 *
 */
FGSErrorRet FGSDrmEnvelopeCopyKey(FGSDrmEnvelopeRef envelope, CFMutableDataRef data);

/**
 * @brief Count the number of the limit .
 *
 * @param[in] envelope				Reference to an envelope.
 *
 * @return	The number of the limit.
 *
 */
SInt32 FGSDrmEnvelopeCountLimits(FGSDrmEnvelopeRef envelope);

/**
 * @brief Get the limit type.
 *
 * @param[in] envelope				Reference to an envelope.
 * @param[in] index					The index of the limit.
 *
 * @return	The limit type string, user should release the string by calling <b>CFRelease</b>.
 *
 */
CFStringRef	FGSDrmEnvelopeCopyLimitType(FGSDrmEnvelopeRef envelope, SInt32 index);

/**
 * @brief Get the limit value.
 *
 * @param[in] envelope				Reference to an envelope.
 * @param[in] index					The index of the limit.
 *
 * @return	The limit value string, user should release the string by calling <b>CFRelease</b>.
 *
 */
CFStringRef FGSDrmEnvelopeCopyLimitValue(FGSDrmEnvelopeRef envelope, SInt32 index);

/**
 * @brief Count the number of rights.
 *
 * @param[in] envelope				Reference to an envelope.
 *
 * @return	The number of the right.
 *
 */
SInt32 FGSDrmEnvelopeCountRights(FGSDrmEnvelopeRef envelope);

/**
 * @brief Get the right.
 *
 * @param[in] envelope				Reference to an envelope.
 * @param[in] index					The index of the right.
 *
 * @return	The right string, user should release the string by calling <b>CFRelease</b>.
 *
 */
CFStringRef	FGSDrmEnvelopeCopyRight(FGSDrmEnvelopeRef envelope, SInt32 index);

/** 
 * @brief	Create RSA private key and public key.
 *
 * @param[in]	length			The length of the key(eg.1024, 2048...).
 * @param[in]	seed			A seed, which is a byte for generating keys.
 * @param[in]	password		The password used to encrypt private key.(now not support).
 * @param[out]	publicKey		The MutableData to store private key.
 * @param[out]	privateKey		The MutableData to store public key.
 *
 * @return		::kFGSErrorSuccess means successfully.<br>
 *			For more definitions please see enum definitions <b>FGSErrorRet</b>.
 */
FGSErrorRet FGSDrmPkiRsaCreateKey(SInt32 length, CFDataRef seed, CFDataRef password, CFMutableDataRef publicKey, CFMutableDataRef privateKey);

/** 
 * @brief	Encrypt data used by RSA public key.
 *
 * @param[in]	data		The data which needs to be encrypted, the data length must be bigger than 4 bytes, otherwise, can't be encrypted.
 * @param[in]	pubKey		The public key for encrypting.
 * @param[out]	result		The MutableData to store encrypted data.
 * 
 * @return	None.
 */
void FGSDrmPkiRsaEncrypt(CFStringRef data, CFDataRef pubKey, CFMutableDataRef result);

/** 
 * @brief	Decrypt data used by RSA private key.
 *
 * @param[in]	data		The data which needs to be decrypted.
 * @param[in]	priKey		The private key for decrypting.
 * @param[out]	result		The MutableData to store decrypted data.
 * 
 * @return	   The decrypted data.
 */
void FGSDrmPkiRsaDecrypt(CFDataRef data, CFDataRef priKey, CFMutableDataRef result);

#ifdef __cplusplus
};
#endif

#endif // __FGSDRM__
/**@}*/
